﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Newtonsoft.Json.Linq;

namespace TinyLayoutTool
{
    public enum SpliterType
    {
        Horizontal,
        Vertical
    }
    public class SpliterNode
    {
        public Rectangle rect = new Rectangle();
        public Rectangle leftRect = new Rectangle(); // 左 上
        public Rectangle rightRect = new Rectangle(); // 右 下
        public int pos = 0;
        public SpliterType type = SpliterType.Horizontal;
        public SpliterNode leftNode = null;
        public SpliterNode rightNode = null;
        public SpliterNode parentNode = null;
        public IntPtr leftHwnd = IntPtr.Zero;
        public IntPtr rightHwnd = IntPtr.Zero;

        public SpliterNode()
        {
            InitNode(0, 0, 100, 100, 50, SpliterType.Horizontal);
        }

        public SpliterNode(int x, int y, int width, int height, int pos, SpliterType type)
        {
            InitNode(x, y, width, height, pos, type);
        }
        public SpliterNode(Rectangle rect, int pos, SpliterType type)
        {
            InitNode(rect.X, rect.Y, rect.Width, rect.Height, pos, type);
        }

        private void InitNode(int x, int y, int width, int height, int pos, SpliterType type)
        {
            rect.X = x;
            rect.Y = y;
            rect.Width = width;
            rect.Height = height;
            this.type = type;

            // 更新位置
            UpdatePos(pos);
            // 刷新子范围
            RefreshSubRect();
        }

        public void UpdatePos(int pos)
        {
            if (this.type == SpliterType.Horizontal)
            {
                if (pos < rect.Y)
                {
                    this.pos = rect.Y;
                }
                else if (pos > rect.Y + rect.Height)
                {
                    this.pos = rect.Y + rect.Height;
                }
                else
                {
                    this.pos = pos;
                }
            }
            else
            {
                if (pos < rect.X)
                {
                    this.pos = rect.X;
                }
                else if (pos > rect.X + rect.Width)
                {
                    this.pos = rect.X + rect.Width;
                }
                else
                {
                    this.pos = pos;
                }
            }
        }

        public void RefreshRect(Rectangle rect)
        {
            this.rect.X = rect.X;
            this.rect.Y = rect.Y;
            this.rect.Width = rect.Width;
            this.rect.Height = rect.Height;
            UpdatePos(pos);
        }

        public void RefreshSubRect()
        {
            if(type == SpliterType.Horizontal)
            {
                leftRect.X = rect.Left;
                leftRect.Y = rect.Top;
                leftRect.Width = rect.Width;
                leftRect.Height = pos - rect.Top;

                rightRect.X = rect.Left;
                rightRect.Y = pos;
                rightRect.Width = rect.Width;
                rightRect.Height = rect.Bottom - pos;
            }
            else
            {
                leftRect.X = rect.Left;
                leftRect.Y = rect.Top;
                leftRect.Width = pos - rect.Left;
                leftRect.Height = rect.Height;

                rightRect.X = pos;
                rightRect.Y = rect.Top;
                rightRect.Width = rect.Right - pos;
                rightRect.Height = rect.Height;
            }
        }

        public bool IsMouseHover(int x, int y)
        {
            Rectangle tmpRect = new Rectangle();
            if(type == SpliterType.Horizontal)
            {
                tmpRect.X = rect.X;
                tmpRect.Y = pos - 1;
                tmpRect.Width = rect.Width;
                tmpRect.Height = 3;
            }
            else if (type == SpliterType.Vertical)
            {
                tmpRect.X = pos - 1;
                tmpRect.Y = rect.Y;
                tmpRect.Width = 3;
                tmpRect.Height = rect.Height;
            }

            return tmpRect.Contains(x, y);
        }

        public JObject ToJsonObject()
        {
            JObject jObj = new JObject();

            JObject rectObj = RectToJsonObject(rect);
            jObj["rect"] = rectObj;
            jObj["pos"] = pos;
            jObj["type"] = (int)type;
            if (leftNode != null)
            {
                jObj["leftNode"] = leftNode.ToJsonObject();
            }
            if (rightNode != null)
            {
                jObj["rightNode"] = rightNode.ToJsonObject();
            }
            return jObj;
        }

        public void FromJsonObject(JObject jObj)
        {
            if (jObj != null)
            {
                if (jObj.Property("rect") != null)
                {
                    JObject tmp = (JObject)jObj.Property("rect").Value;
                    RectFromJsonObject(tmp, ref rect);
                }
                if (jObj.Property("pos") != null)
                {
                    string str = jObj.Property("pos").Value.ToString();
                    int value = 0;
                    int.TryParse(str, out value);
                    pos = value;
                }
                if (jObj.Property("type") != null)
                {
                    string str = jObj.Property("type").Value.ToString();
                    int value = 0;
                    int.TryParse(str, out value);
                    type = (SpliterType)value;
                }
                if (jObj.Property("leftNode") != null)
                {
                    JObject tmp = (JObject)jObj.Property("leftNode").Value;
                    leftNode = new SpliterNode();
                    leftNode.FromJsonObject(tmp);
                }
                else
                {
                    leftNode = null;
                }
                if (jObj.Property("rightNode") != null)
                {
                    JObject tmp = (JObject)jObj.Property("rightNode").Value;
                    rightNode = new SpliterNode();
                    rightNode.FromJsonObject(tmp);
                }
                else
                {
                    rightNode = null;
                }
            }
        }

        public JObject RectToJsonObject(Rectangle rect)
        {
            JObject jObj = new JObject();
            jObj["x"] = rect.X;
            jObj["y"] = rect.Y;
            jObj["width"] = rect.Width;
            jObj["height"] = rect.Height;
            return jObj;
        }

        public void RectFromJsonObject(JObject jObj, ref Rectangle rect)
        {
            if(jObj != null)
            {
                if (jObj.Property("x") != null)
                {
                    string str = jObj.Property("x").Value.ToString();
                    int value = 0;
                    int.TryParse(str, out value);
                    rect.X = value;
                }
                if (jObj.Property("y") != null)
                {
                    string str = jObj.Property("y").Value.ToString();
                    int value = 0;
                    int.TryParse(str, out value);
                    rect.Y = value;
                }
                if (jObj.Property("width") != null)
                {
                    string str = jObj.Property("width").Value.ToString();
                    int value = 0;
                    int.TryParse(str, out value);
                    rect.Width = value;
                }
                if (jObj.Property("height") != null)
                {
                    string str = jObj.Property("height").Value.ToString();
                    int value = 0;
                    int.TryParse(str, out value);
                    rect.Height = value;
                }
            }
        }
    }
}
